```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Docker 容器化技术完全指南</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', 'Noto Serif SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Hiragino Sans GB", Simsun, sans-serif;
            color: #2d3748;
            line-height: 1.6;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .code-block {
            background-color: #2d3748;
            border-radius: 0.5rem;
            padding: 1.5rem;
            position: relative;
        }
        .code-block pre {
            margin: 0;
            color: #e2e8f0;
            font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
            font-size: 0.875rem;
            line-height: 1.5;
            overflow-x: auto;
        }
        .code-block .lang {
            position: absolute;
            top: 0;
            right: 0;
            background-color: #4a5568;
            color: white;
            padding: 0.25rem 0.75rem;
            border-bottom-left-radius: 0.5rem;
            font-size: 0.75rem;
        }
        .comparison-table {
            background: white;
            border-radius: 0.5rem;
            overflow: hidden;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
        }
        .comparison-table th {
            background-color: #4a5568;
            color: white;
            padding: 1rem;
            font-weight: 600;
        }
        .comparison-table td {
            padding: 1.5rem;
            vertical-align: top;
            border-bottom: 1px solid #e2e8f0;
        }
        .comparison-table img {
            max-width: 100%;
            height: auto;
            border-radius: 0.25rem;
        }
        .highlight {
            background-color: #fffde7;
            padding: 0.25rem 0.5rem;
            border-radius: 0.25rem;
            font-weight: 500;
        }
        .feature-card {
            transition: all 0.3s ease;
            border-radius: 0.5rem;
            overflow: hidden;
        }
        .feature-card:hover {
            transform: translateY(-4px);
            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
        }
        .section-divider {
            height: 1px;
            background: linear-gradient(to right, transparent, #a0aec0, transparent);
            margin: 3rem 0;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <div class="hero-gradient text-white py-20 px-6">
        <div class="max-w-6xl mx-auto">
            <div class="flex flex-col lg:flex-row items-center">
                <div class="lg:w-1/2 mb-10 lg:mb-0 lg:pr-10">
                    <h1 class="text-4xl md:text-5xl font-bold mb-6 leading-tight">Docker 容器化技术完全指南</h1>
                    <p class="text-xl opacity-90 mb-8">掌握现代应用部署与管理的核心技术</p>
                    <div class="flex flex-wrap gap-4">
                        <div class="bg-white bg-opacity-20 px-4 py-2 rounded-full flex items-center">
                            <i class="fas fa-box-open mr-2"></i>
                            <span>容器引擎</span>
                        </div>
                        <div class="bg-white bg-opacity-20 px-4 py-2 rounded-full flex items-center">
                            <i class="fas fa-rocket mr-2"></i>
                            <span>轻量虚拟化</span>
                        </div>
                        <div class="bg-white bg-opacity-20 px-4 py-2 rounded-full flex items-center">
                            <i class="fas fa-layer-group mr-2"></i>
                            <span>微服务架构</span>
                        </div>
                    </div>
                </div>
                <div class="lg:w-1/2">
                    <div class="bg-white bg-opacity-20 p-2 rounded-lg">
                        <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1710909987206-47086b02-1b62-46fc-a642-ca13cdd5118f.png" alt="Docker Architecture" class="rounded-lg shadow-xl">
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Main Content -->
    <div class="max-w-6xl mx-auto px-6 py-12">
        <!-- What is Docker -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                <span class="bg-blue-100 text-blue-600 w-10 h-10 rounded-full flex items-center justify-center mr-4">1</span>
                什么是 Docker
            </h2>
            <div class="bg-white rounded-xl shadow-md overflow-hidden">
                <div class="p-6 md:p-8">
                    <p class="text-gray-700 mb-6">Docker 是 Docker Inc 公司开源的一个基于 LXC (Linux Container) 技术之上搭建的 <span class="highlight">容器引擎</span>，源代码托管在 GitHub 上，基于 Go 语言并遵从 Apache 2.0 协议开源。</p>
                    
                    <div class="flex justify-center my-8">
                        <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1710909987206-47086b02-1b62-46fc-a642-ca13cdd5118f.png" alt="Docker Architecture" class="max-w-full rounded-lg shadow-md">
                    </div>
                    
                    <div class="grid md:grid-cols-2 gap-6 mt-8">
                        <div class="feature-card bg-white border border-gray-200 p-6 rounded-lg">
                            <div class="text-blue-500 mb-4 text-2xl">
                                <i class="fas fa-cube"></i>
                            </div>
                            <h3 class="text-xl font-semibold mb-3">应用程序打包</h3>
                            <p class="text-gray-600">Docker 将应用程序与该程序的依赖，打包在一个文件里面。运行这个文件，就会生成一个虚拟容器。程序在这个虚拟容器里运行，就好像在真实的物理机上运行一样。</p>
                        </div>
                        <div class="feature-card bg-white border border-gray-200 p-6 rounded-lg">
                            <div class="text-green-500 mb-4 text-2xl">
                                <i class="fas fa-code-branch"></i>
                            </div>
                            <h3 class="text-xl font-semibold mb-3">版本管理与共享</h3>
                            <p class="text-gray-600">Docker 的接口相当简单，用户可以方便地创建和使用容器，把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改，就像管理普通的代码一样。</p>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Why Docker -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                <span class="bg-blue-100 text-blue-600 w-10 h-10 rounded-full flex items-center justify-center mr-4">2</span>
                为什么要用 Docker
            </h2>
            
            <!-- Virtual Machine -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-700">2.1 虚拟机技术</h3>
                <div class="bg-white rounded-xl shadow-md overflow-hidden">
                    <div class="p-6 md:p-8">
                        <p class="text-gray-700 mb-6">虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统，比如在 Windows 系统里面运行 Linux 系统。应用程序对此毫无感知，因为虚拟机看上去跟真实系统一模一样，而对于底层系统来说，虚拟机就是一个普通文件，不需要了就删掉，对其它部分毫无影响。</p>
                        
                        <div class="flex justify-center my-8">
                            <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1710910128778-6293e096-46eb-425f-b8ff-be887216d56c.png" alt="Virtual Machine Architecture" class="max-w-full rounded-lg shadow-md">
                        </div>
                        
                        <h4 class="text-xl font-semibold mb-3 text-red-600">虚拟机的缺点：</h4>
                        <ul class="list-disc pl-6 space-y-2 text-gray-700">
                            <li><span class="font-medium">资源占用多</span>：虚拟机会独占一部分内存和硬盘空间。它运行的时候，其他程序就不能使用这些资源了。哪怕虚拟机里面的应用程序，真正使用的内存只有 1M，虚拟机依然需要几百 MB 的内容才能运行。</li>
                            <li><span class="font-medium">启动慢</span>：启动操作系统需要多久，启动虚拟机就需要多久。可能要等几分钟，应用程序才能真正运行。</li>
                        </ul>
                    </div>
                </div>
            </div>
            
            <!-- Linux Container -->
            <div class="mb-12">
                <h3 class="text-2xl font-semibold mb-4 text-gray-700">2.2 Linux 容器</h3>
                <div class="bg-white rounded-xl shadow-md overflow-hidden">
                    <div class="p-6 md:p-8">
                        <p class="text-gray-700 mb-6">由于虚拟机存在这些缺点，Linux 发展出了另一种虚拟化技术：Linux 容器(Linux Containers,缩写为 LXC)。Linux 容器不是模拟一个完整的操作系统，而是对进程进行隔离。或者说，在正常进程的外面套了一个保护层。对于容器里面的进程来说，它接触到的各种资源都是虚拟的，从而实现与底层系统的隔离。由于容器是进程级别的，相比虚拟机有很多优势。<span class="highlight">Docker 在一定程度上是 LXC 的增强版</span>。</p>
                        
                        <div class="flex justify-center my-8">
                            <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1710910173248-3e22f0fc-48f0-47a4-8ac5-b2878424aedd.png" alt="Linux Container Architecture" class="max-w-full rounded-lg shadow-md">
                        </div>
                        
                        <div class="grid md:grid-cols-3 gap-6 mt-8">
                            <div class="feature-card bg-white border border-gray-200 p-6 rounded-lg">
                                <div class="text-green-500 mb-4 text-2xl">
                                    <i class="fas fa-bolt"></i>
                                </div>
                                <h4 class="text-lg font-semibold mb-2">启动快</h4>
                                <p class="text-gray-600 text-sm">启动容器相当于启动本机的一个进程，而不是启动一个操作系统，速度就快很多。</p>
                            </div>
                            <div class="feature-card bg-white border border-gray-200 p-6 rounded-lg">
                                <div class="text-blue-500 mb-4 text-2xl">
                                    <i class="fas fa-memory"></i>
                                </div>
                                <h4 class="text-lg font-semibold mb-2">资源占用少</h4>
                                <p class="text-gray-600 text-sm">容器只占用需要的资源，不占用那些没有用到的资源；虚拟机由于是完整的操作系统，不可避免要占用所有资源。</p>
                            </div>
                            <div class="feature-card bg-white border border-gray-200 p-6 rounded-lg">
                                <div class="text-purple-500 mb-4 text-2xl">
                                    <i class="fas fa-compress-alt"></i>
                                </div>
                                <h4 class="text-lg font-semibold mb-2">体积小</h4>
                                <p class="text-gray-600 text-sm">容器只要包含用到的组件即可，而虚拟机是整个操作系统的打包，所以容器文件比虚拟机文件要小很多。</p>
                            </div>
                        </div>
                        
                        <p class="text-gray-700 mt-8"><span class="highlight">总之，容器有点像轻量级的虚拟机，能够提供虚拟化的环境，但是成本开销小得多。</span></p>
                    </div>
                </div>
            </div>
            
            <!-- Docker vs VM -->
            <div>
                <h3 class="text-2xl font-semibold mb-4 text-gray-700">2.3 Docker 与传统虚拟机的区别</h3>
                <div class="bg-white rounded-xl shadow-md overflow-hidden">
                    <div class="p-6 md:p-8">
                        <ul class="list-decimal pl-6 space-y-3 text-gray-700 mb-6">
                            <li>docker 直接构建在 Linux 操作系统之上，其使用的内核为当前<span class="highlight">宿主机</span>的内核；虚拟机一般构建在虚拟机管理软件之上，拥有独立的内核</li>
                            <li>由于 docker 直接使用宿主机内核所以其性能接近宿主机性能；虚拟机使用自己的内核，但是其内核也是虚拟出来的所以需要进行两级调度性能相对较差。</li>
                            <li>docker 相对虚拟机更加轻量，部署和运行更加方便快捷。</li>
                        </ul>
                        
                        <div class="comparison-table mt-8">
                            <table class="w-full">
                                <thead>
                                    <tr>
                                        <th class="text-center">容器</th>
                                        <th class="text-center">虚拟机</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr>
                                        <td class="text-center"><img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617745935-fb92a9c4-1ffe-4040-bced-c2034cd70126.png" alt="Container Architecture"></td>
                                        <td class="text-center"><img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617746277-c2fcff9c-4934-4d82-9ebe-0bba12ff42a6.png" alt="VM Architecture"></td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <!-- Docker Terminology -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                <span class="bg-blue-100 text-blue-600 w-10 h-10 rounded-full flex items-center justify-center mr-4">3</span>
                Docker 术语
            </h2>
            <div class="grid md:grid-cols-3 gap-6">
                <div class="feature-card bg-white border border-gray-200 p-6 rounded-lg shadow-md">
                    <div class="text-blue-500 mb-4 text-3xl">
                        <i class="fas fa-box"></i>
                    </div>
                    <h3 class="text-xl font-semibold mb-3">镜像(Image)</h3>
                    <p class="text-gray-600">只读模板，Docker 镜像是用于创建 Docker 容器的模板。</p>
                </div>
                <div class="feature-card bg-white border border-gray-200 p-6 rounded-lg shadow-md">
                    <div class="text-green-500 mb-4 text-3xl">
                        <i class="fas fa-cube"></i>
                    </div>
                    <h3 class="text-xl font-semibold mb-3">容器(Container)</h3>
                    <p class="text-gray-600">实例化的镜像，在只读层上增加了一层可写层，容器可以启动，停止，删除和修改每个容器都是相互隔离的。</p>
                </div>
                <div class="feature-card bg-white border border-gray-200 p-6 rounded-lg shadow-md">
                    <div class="text-purple-500 mb-4 text-3xl">
                        <i class="fas fa-warehouse"></i>
                    </div>
                    <h3 class="text-xl font-semibold mb-3">仓库(Repository)</h3>
                    <p class="text-gray-600">集中存放镜像的地方，仓库分为公开仓库(Public)和私有仓库(Private)两种形式世界上最大的公开仓库是 Docker Hub，国内的公开仓库 Docker Pool 等。</p>
                </div>
            </div>
        </section>

        <!-- Docker Installation -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                <span class="bg-blue-100 text-blue-600 w-10 h-10 rounded-full flex items-center justify-center mr-4">4</span>
                Docker 安装
            </h2>
            
            <div class="bg-white rounded-xl shadow-md overflow-hidden">
                <div class="p-6 md:p-8">
                    <p class="text-gray-700 mb-6">Linux 安装软件的三种方式：</p>
                    <ul class="list-disc pl-6 space-y-2 text-gray-700 mb-8">
                        <li>rpm 工具</li>
                        <li>yum 工具</li>
                        <li>安装源码包</li>
                    </ul>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">4.1 安装前置环境</h3>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>yum install -y yum-utils device-mapper-persistent-data lvm2</code></pre>
                    </div>
                    <div class="flex justify-center mb-8">
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617746761-b2032b46-284e-423a-b581-72779bc4d1a9.png" alt="Pre-installation" class="rounded-lg shadow-md">
                    </div>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">4.2 安装 docker 源</h3>
                    <p class="text-gray-700 mb-4">Docker 有两个版本，ce 版(社区版，免费)，ee 版(企业版,收费)</p>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo</code></pre>
                    </div>
                    <div class="flex justify-center mb-8">
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617746978-b2932381-bffb-4a03-bfd7-66bc6d9c1833.png" alt="Add Docker Repo" class="rounded-lg shadow-md">
                    </div>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">4.3 安装 docker</h3>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>yum -y install docker-ce</code></pre>
                    </div>
                    <div class="flex justify-center mb-8">
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617747355-9b9d97cf-e289-4663-95f0-0423530fd004.png" alt="Install Docker" class="rounded-lg shadow-md">
                    </div>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">4.4 启动 docker 服务</h3>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>systemctl start docker</code></pre>
                    </div>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">4.5 配置镜像加速</h3>
                    <p class="text-gray-700 mb-4">新建一个文件： /etc/docker/daemon.json，内容为：</p>
                    <div class="code-block mb-4">
                        <span class="lang">JSON</span>
                        <pre><code>{
  "registry-mirrors": ["https://4p6hldmh.mirror.aliyuncs.com"]
}</code></pre>
                    </div>
                    <p class="text-red-600 font-medium mb-8">重启 docker 服务 systemctl restart docker</p>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">4.6 测试 Docker</h3>
                    <p class="text-gray-700 mb-4">docker run hello-world (是官方提供的一个测试镜像，专门用来测试 docker 是否可用)</p>
                </div>
            </div>
        </section>

        <!-- Docker Commands -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                <span class="bg-blue-100 text-blue-600 w-10 h-10 rounded-full flex items-center justify-center mr-4">5</span>
                Docker 常用命令
            </h2>
            <div class="bg-white rounded-xl shadow-md overflow-hidden">
                <div class="p-6 md:p-8">
                    <div class="flex justify-center">
                        <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1710910300679-f8e39021-bac3-493a-8b4e-e09e5ca4771a.png" alt="Docker Commands" class="max-w-full rounded-lg shadow-md">
                    </div>
                </div>
            </div>
        </section>

        <!-- Docker Volume -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                <span class="bg-blue-100 text-blue-600 w-10 h-10 rounded-full flex items-center justify-center mr-4">6</span>
                Docker 容器卷
            </h2>
            
            <div class="bg-white rounded-xl shadow-md overflow-hidden">
                <div class="p-6 md:p-8">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">6.1 什么是容器卷</h3>
                    <p class="text-gray-700 mb-6">数据卷存在于<span class="highlight">宿主机</span>中，独立于容器，和容器的生命周期是分离的，数据卷存在于宿主机的文件系统中，数据卷可以目录也可以是文件，容器可以利用数据卷与宿主机进行数据共享，实现了容器间的<span class="highlight">数据共享</span>和交换。</p>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">6.2 容器卷特点</h3>
                    <ul class="list-disc pl-6 space-y-2 text-gray-700 mb-6">
                        <li>容器卷可以在容器之间共享或者重用数据</li>
                        <li>容器卷中的更改可以直接生效</li>
                        <li>容器卷中的更改不会包含在镜像的更新中</li>
                        <li>容器卷的生命周期一直持续到没有容器使用它为止</li>
                    </ul>
                    
                    <p class="text-gray-700 mb-4">一般都在创建容器的时候映射容器卷，语法如下：</p>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>docker run -it --name mycentos -v /usr/local/mycentos1:/usr/local/mycentos2 centos</code></pre>
                    </div>
                    <p class="text-gray-700">绿色是宿主机地址，蓝色是容器地址，如果地址不存在容器会自动创建。</p>
                </div>
            </div>
        </section>

        <!-- Docker FastDFS -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                <span class="bg-blue-100 text-blue-600 w-10 h-10 rounded-full flex items-center justify-center mr-4">7</span>
                Docker 安装 FastDFS
            </h2>
            
            <div class="bg-white rounded-xl shadow-md overflow-hidden">
                <div class="p-6 md:p-8">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">7.1 用 Docker 搜索 FastDFS 相关镜像</h3>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>docker search fastdfs</code></pre>
                    </div>
                    <div class="flex justify-center mb-8">
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617747881-0916b96c-8a90-4547-8c0b-4ebde82aa767.png" alt="Search FastDFS" class="rounded-lg shadow-md">
                    </div>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">7.2 拉取相关镜像</h3>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>docker pull ygqygq2/fastdfs-nginx</code></pre>
                    </div>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">7.3 根据镜像创建容器，运行 tracker 服务 22122</h3>
                    <div class="code-block mb-4">
                        <span class="lang">Shell</span>
                        <pre><code>docker run -d --network=host --name tracker -v /usr/local/fdfs/tracker:/var/fdfs ygqygq2/fastdfs-nginx tracker</code></pre>
                    </div>
                    <p class="text-gray-700 mb-8">说明: --network=host 表示容器和宿主机共享同一个网络和端口。 -v:表示容器和宿主机映射一个数据卷 -d:后台运行</p>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">7.4 根据镜像创建容器，运行 storage 服务 Nginx 服务 23000</h3>
                    <div class="code-block mb-4">
                        <span class="lang">Shell</span>
                        <pre><code>docker run -d --network=host --name storage0 -e TRACKER_SERVER=<span class="text-red-500">192.168.189.137</span>:22122 -v /usr/local/fdfs/storage0:/var/fdfs ygqygq2/fastdfs-nginx storage</code></pre>
                    </div>
                    <p class="text-gray-700 mb-8">因为 storage 中 Nginx 默认端口号是 8080,我们宿主机中已有一个 tomcat 启动,所以导致 nginx 启动失败，解决办法修改 Nginx 的端口为 80，然后进入到 storage 容器启动 nginx。 cd /usr/local/nginx/sbin ./nginx</p>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">7.5 第二次启动 tracker 和 storage 服务</h3>
                    <p class="text-gray-700 mb-4">1.先查询以往运行过的所有容器，找到这个两个服务</p>
                    <div class="code-block mb-4">
                        <span class="lang">Shell</span>
                        <pre><code>docker ps -a</code></pre>
                    </div>
                    <div class="flex justify-center mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617748389-eb21dae3-bc11-4311-8f74-f3174761b982.png" alt="Docker PS" class="rounded-lg shadow-md">
                    </div>
                    <p class="text-gray-700 mb-4">2.找到对应的对应的服务后，根据 ID 启动</p>
                    <div class="code-block mb-4">
                        <span class="lang">Shell</span>
                        <pre><code>docker start a8da2539e996</code></pre>
                    </div>
                    <p class="text-gray-700 mb-8">3.如有需要进入到容器中进行相关操作</p>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>docker exec -i -t a8da2539e996 /bin/bash</code></pre>
                    </div>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">7.6 SpringBoot 整合 FastDFS</h3>
                    <h4 class="text-xl font-semibold mb-3 text-gray-600">1. 添加依赖</h4>
                    <div class="code-block mb-8">
                        <span class="lang">XML</span>
                        <pre><code>&lt;dependency&gt;    
  &lt;groupId&gt;com.github.tobato&lt;/groupId&gt;    
  &lt;artifactId&gt;fastdfs-client&lt;/artifactId&gt;    
  &lt;version&gt;1.26.1-RELEASE&lt;/version&gt;   
&lt;/dependency&gt;</code></pre>
                    </div>
                    
                    <h4 class="text-xl font-semibold mb-3 text-gray-600">2. 导入配置</h4>
                    <div class="code-block mb-8">
                        <span class="lang">Java</span>
                        <pre><code>@SpringBootApplication(scanBasePackages = "com.qf")
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class ShopBackApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShopBackApplication.class, args);
    }
}</code></pre>
                    </div>
                    
                    <h4 class="text-xl font-semibold mb-3 text-gray-600">3. application.properties 中配置</h4>
                    <div class="code-block mb-8">
                        <span class="lang">Properties</span>
                        <pre><code>#上传的超时时间
fdfs.connect-timeout=10000
#连接超时时间
fdfs.so-timeout=10000
#缩略图生成参数
fdfs.thumb-image.height=100
fdfs.thumb-image.width=100

#TrackerList参数,支持多个
fdfs.tracker-list[0]=192.168.189.137:22122

#FastDFS服务器的路径   fastdfspath=http://192.168.189.137:8080/</code></pre>
                    </div>
                    
                    <h4 class="text-xl font-semibold mb-3 text-gray-600">4. 上传文件 Controller</h4>
                    <div class="code-block mb-8">
                        <span class="lang">Java</span>
                        <pre><code>@Controller
public class CommonController {

    @Value("${fastdfspath}")
    private String fastdfspath;

    @Autowired
    private FastFileStorageClient ffsc;

    @ResponseBody
    @RequestMapping(value = "/uploadFile")
    public String uploadFile(MultipartFile file){
        System.out.println(file);
        //截取源图片的后缀
        String originalFilename = file.getOriginalFilename();
        int index = originalFilename.lastIndexOf(".");
        String houzhui = originalFilename.substring(index + 1);
        String uploadFile = "";
        try {
            StorePath storePath = ffsc.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), houzhui, null);
            uploadFile = storePath.getFullPath();
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("file:"+fastdfspath+uploadFile);
        return fastdfspath+uploadFile;
    }
}</code></pre>
                    </div>
                </div>
            </div>
        </section>

        <!-- Docker Solr -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-6 text-gray-800 flex items-center">
                <span class="bg-blue-100 text-blue-600 w-10 h-10 rounded-full flex items-center justify-center mr-4">8</span>
                Docker 安装 Solr
            </h2>
            
            <div class="bg-white rounded-xl shadow-md overflow-hidden">
                <div class="p-6 md:p-8">
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">8.1 搜索 Solr 镜像</h3>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>docker search solr</code></pre>
                    </div>
                    <div class="flex justify-center mb-8">
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617748938-64bf8f68-4271-491c-b2a2-f0849ba74f9c.png" alt="Search Solr" class="rounded-lg shadow-md">
                    </div>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">8.2 拉取 Solr 镜像</h3>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>docker pull solr</code></pre>
                    </div>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">8.3 创建一个 solr 容器</h3>
                    <div class="code-block mb-4">
                        <span class="lang">Shell</span>
                        <pre><code>docker run -d --name mysolr -p 8983:8983 solr</code></pre>
                    </div>
                    <p class="text-gray-700 mb-4">-d:后台运行 --name:别名 -p:指定宿主机和容器的端口要映射</p>
                    <p class="text-gray-700 mb-8">浏览器访问: http://服务器IP:8983</p>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">8.4 配置 solr 的 solrcore</h3>
                    <div class="code-block mb-8">
                        <span class="lang">Shell</span>
                        <pre><code>docker exec -it mysolr bin/solr create_core -c mycollection</code></pre>
                    </div>
                    <p class="text-gray-700 mb-8">命令说明:给 mysolr 发送一个指令，执行当前路径下的 bin/solr 命令，创建一个 mycollection 的 solrcore</p>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">8.5 查看 solr 数据卷在宿主机中对应的位置</h3>
                    <div class="code-block mb-4">
                        <span class="lang">Shell</span>
                        <pre><code>docker inspect mysolr</code></pre>
                    </div>
                    <div class="flex justify-center mb-8">
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617749144-f74d51bb-5935-4056-a1a4-ecbe09a62e44.png" alt="Docker Inspect" class="rounded-lg shadow-md">
                    </div>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">8.6 配置中文分词器</h3>
                    <p class="text-gray-700 mb-4">1. 进入到容器中 docker exec -it mysolr /bin/bash</p>
                    <p class="text-gray-700 mb-4">2. solr 自带的中文分词器路径: /opt/solr/<span class="highlight">contrib/analysis-extras/lucene-libs/</span></p>
                    <div class="flex justify-center mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617749581-4c4bea4b-92e7-469a-8088-199290b8d5e2.png" alt="Chinese Analyzer" class="rounded-lg shadow-md">
                    </div>
                    <p class="text-gray-700 mb-4">lucene-analyzers-smartcn-8.1.1.jar</p>
                    <p class="text-gray-700 mb-4">3. 在宿主机映射的路径(Mounts 中的路径)中配置分词器:;</p>
                    <p class="text-gray-700 mb-4"><span class="highlight">/var/lib/docker/volumes/8ffb9396c028481dedc3db2eda495f62a84875239b06127b2bffce7f14d2d16f/_data</span>/data/mycollection/conf</p>
                    <p class="text-gray-700 mb-4">4. vim solrconfig.xml</p>
                    <div class="flex justify-center mb-4">
                        <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1652617750139-70f39aa0-acd2-4480-b16b-53f2ffcbbe52.png" alt="Solr Config" class="rounded-lg shadow-md">
                    </div>
                    <p class="text-gray-700 mb-4">5. vim managed-schema</p>
                    <div class="code-block mb-8">
                        <span class="lang">XML</span>
                        <pre><code>&lt;fieldType name="mytext_id" class="solr.TextField"&gt;
    &lt;analyzer type="index"&gt;
        &lt;tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/&gt;
    &lt;/analyzer&gt;
    &lt;analyzer type="query"&gt;
        &lt;tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/&gt;
    &lt;/analyzer&gt;
&lt;/fieldType&gt;</code></pre>
                    </div>
                    <p class="text-gray-700 mb-4">Mytext_id 是分词器的名称。org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory:是刚才配置的中文分词器 query:是查询的时候也要分词</p>
                    <p class="text-gray-700 mb-4">重启 solr 容器 docker restart mysolr,</p>
                    
                    <h4 class="text-xl font-semibold mb-3 text-gray-600">6. 配置 solr 字段域</h4>
                    <p class="text-gray-700 mb-4">vim managed-schema：</p>
                    <div class="code-block mb-8">
                        <span class="lang">XML</span>
                        <pre><code>&lt;!-- 创建自定义的字段 --&gt;
&lt;field name="gname" type="mytext_id" indexed="true" stored="true"/&gt;
&lt;field name="ginfo" type="mytext_id" indexed="true" stored="true"/&gt;
&lt;field name="gimage" type="string" indexed="false" stored="true"/&gt;
&lt;field name="gprice" type="pfloat" indexed="false" stored="true"/&gt;
&lt;field name="gsave" type="pint" indexed="false" stored="true"/&gt;</code></pre>
                    </div>
                    <p class="text-gray-700 mb-4">Indexed:当前字段是否添加到是索引，添加到索引才能进行搜索。 Stored:是否储存到索引库 name:储存到索引库的字段名称 Type:使用哪个分词器进行分词。</p>
                    <p class="text-gray-700 mb-8"><span class="highlight">注意:这里启动 mysolr 必须要开启防火墙，否则启动失败</span></p>
                    
                    <h3 class="text-2xl font-semibold mb-4 text-gray-700">8.7 SpringBoot 整合 Solr</h3>
                    <h4 class="text-xl font-semibold mb-3 text-gray-600">1. 添加依赖</h4>
                    <div class="code-block mb-8">
                        <span class="lang">XML</span>
                        <pre><code>&lt;dependency&gt;    
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;    
    &lt;artifactId&gt;spring-boot-starter-data-solr&lt;/artifactId&gt;    
    &lt;version&gt;2.1.7.RELEASE&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
                    </div>
                    
                    <h4 class="text-xl font-semibold mb-3 text-gray-600">2. 配置 application.properties</h4>
                    <div class="code-block mb-8">
                        <span class="lang">Properties</span>
                        <pre><code>dubbo.application.name=search_server
dubbo.registry.address=zookeeper://192.168.189.137:2181
dubbo.protocol.port=-1
dubbo.registry.register=true

spring.data.solr.host=http://192.168.189.137:8983/solr/mycollection</code></pre>
                    </div>
                    
                    <h4 class="text-xl font-semibold mb-3 text-gray-600">3. 索引库 CRUD</h4>
                    <div class="code-block mb-8">
                        <span class="lang">Java</span>
                        <pre><code>@Test
public void add() throws IOException, SolrServerException {
    SolrInputDocument document = new SolrInputDocument();

    document.addField("gname","华为荣耀20");
    document.addField("ginfo","4800万超广角AI四摄 3200W美颜自拍 麒麟Kirin980全网通版8GB+128GB 幻夜黑 移动联通电信4G全面屏");
    document.setField("gimage","a1.png");
    document.setField("gprice",1399.00 );
    document.setField("gsave",100);
    document.setField("id",1);
    solrClient.add(document); // 如果id存在就更新
    solrClient.commit(); 
}

@Test
public void delete() throws IOException, SolrServerException {
    solrClient.deleteById("a7b2ef4b-2b25-4eb5-b8dd-b6a255d8ca22");
    solrClient.commit();
}

@Test
public void getById() throws IOException, SolrServerException {
    SolrDocument solrDocument = solrClient.getById("9b518e0b-e45e-4f24-a943-bc5b11d2aebf");

    // 1.属性的键值对
    Map&lt;String, Object&gt; fieldValueMap = solrDocument.getFieldValueMap();
    
    // 2.所有的属性名称
    Set&lt;String&gt; fieldNames = (Set&lt;String&gt;)solrDocument.getFieldNames();
    
    // 3.根据属性名称获取属性值
    Object gname = solrDocument.getFieldValue("gname");
    
    // 4.根据属性名称获取属性值，是个数组
    Collection&lt;Object&gt; values = solrDocument.getFieldValues("gname");
    
    // 5.根据属性名称获取属性值
    Object ginfo = solrDocument.get("ginfo");
}

@Test
public void query() throws IOException, SolrServerException {
    SolrQuery solrQuery = new SolrQuery();
    solrQuery.setQuery("gname:华为 || ginfo:手机");       
    QueryResponse queryResponse = solrClient.query(solrQuery);
    SolrDocumentList results = queryResponse.getResults();
    for(SolrDocument sd:results){
        System.out.println(sd.get("gname"));
        System.out.println(sd.get("ginfo"));
    }
}</code></pre>
                    </div>
                    
                    <h4 class="text-xl font-semibold mb-3 text-gray-600">4. 关键字高亮</h4>
                    <div class="code-block mb-8">
                        <span class="lang">Java</span>
                        <pre><code>public List&lt;Goods&gt; selectByKey(String keyword) {
    SolrQuery solrQuery = null;
    List&lt;Goods&gt; goodsList = new ArrayList&lt;Goods&gt;();
    if(!StringUtils.isEmpty(keyword)){
        String queryStr ="gname:%s || ginfo:%s";
        solrQuery = new SolrQuery(String.format(queryStr,keyword,keyword));
    }else{
        solrQuery = new SolrQuery("*:*");
    }
  
    // 处理高亮
    solrQuery.setHighlight(true); // 开启高亮
    solrQuery.setHighlightSimplePre("&lt;font color ='red'&gt;"); // 前缀
    solrQuery.setHighlightSimplePost("&lt;/font&gt;"); // 后缀
  
    solrQuery.addHighlightField("ginfo"); // 设置高亮字段,可以设置多个
  
    try {
        QueryResponse queryResponse = solrClient.query(solrQuery);
        SolrDocumentList results = queryResponse.getResults(); // 获取没有高亮的结果   
        // 获取有高亮的结果&lt;有高亮结果的ID,&lt;高亮字段,高亮内容&gt;&gt;
        Map&lt;String, Map&lt;String, List&lt;String&gt;&gt;&gt; highlighting = queryResponse.getHighlighting();
  
        for(SolrDocument sd:results){
            Goods goods = new Goods();
  
            String id = sd.getFieldValue("id").toString();
            String gname = sd.getFieldValue("gname").toString();
            String ginfo = sd.getFieldValue("ginfo").toString();
            goods.setGname(gname);
            goods.setGinfo(ginfo);
  
            if(highlighting.containsKey(id)){
                // 条件成立说明这条记录有高亮内容
                Map&lt;String, List&lt;String&gt;&gt; listMap = highlighting.get(id);
                if(listMap.containsKey("ginfo")){ // 判断这条记录中gname是否有高亮
                    String hightLiGinfo = listMap.get("ginfo").get(0); // 获取高亮内容
                    goods.setGinfo(hightLiGinfo);
                }
            }
            goodsList.add(goods);
        }
    } catch (SolrServerException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return goodsList;
}</code></pre>
                    </div>
                    
                    <h4 class="text-xl font-semibold mb-3 text-gray-600">5. 页面显示高亮</h4>
                    <div class="code-block">
                        <span class="lang">HTML</span>
                        <pre><code>&lt;p class="miaoshu" th:utext="${goods.ginfo}"&gt;&lt;/p&gt;</code></pre>
                    </div>
                </div>
            </div>
        </section>
    </div>

    <!-- Mermaid Diagrams -->
    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: false,
                htmlLabels: true
            }
        });
    </script>
</body>
</html>
```